async
與 defer
是 <script>
中很常見的屬性,現在的前端框架中幾乎都幫我們處理掉這部分,不過還是必須要理解一下兩者的差別與使用時機:
一般在執行 JS 時,為了避免 DOM 尚未渲染完成就跑 JS 檔,導致問題發生,我們會把 <script>
放到 HTML 檔案中的後面。
但如果放在中間會發生什麼事?
<p>Hello World</p>
<script src="./app.js"></script>
<p>Bye Bye</p>
最後一行的 Bye Bye
必須等到上方的 script
載入完成後才會執行,再發起請求後瀏覽器只會乖乖地等待,一旦外部資源過多就會讓網頁卡超久。
async
是 asynchronous 的縮寫,代表 非同步。
也就是說不用等待資源執行完畢就可以繼續跑下面的程式,添加 async
的 <script>
會在背景持續下載,一旦下載完成後會暫停解析 DOM,因為沒辦法確定 DOM 的狀況,所以通常會用在 GA 或是其他廣告的追蹤碼。
<script async src="app.js"></script>
defer
是 Deferred 的縮寫,代表 延遲。
作用與 async
相同,同樣會在背景執行,差別在於 defer
會等到 DOM 都解析完成後才執行(DOMContentLoaded 之前)。在 JS 檔有多個相依性、且要等 DOM 準備好才使用的情況下,defer
是很棒的選擇。
<script defer src="app.js"></script>
備註:DOMContentLoaded
事件是在 DOM 結構被完整的讀取跟解析後就會被觸發,詳細可以參考 重新認識 JavaScript 番外篇 (6) - 網頁的生命週期。
另外,在 script
中也會很常看見 type="module"
,這個東西留到下一篇的 CommonJS 再一併解說囉。